#include "tuya_uart.h"
#include "gd32e23x_it.h"
#include <string.h>

/*#define UART_RECV_VER          0
#define UART_SEND_VER          3
#define UART_RECV_SIZE         512
#define UART_SEND_SIZE         512
uint8_t uart_recv_buf[UART_RECV_SIZE];
uint8_t uart_send_buf[UART_SEND_SIZE];

#define FRAME_RECV_START        0
#define FRAME_RECV_ING          1
#define FRAME_RECV_END          2
static volatile uint8_t frame_state;

#define CMD_HEART_BEAT                 0x0
#define CMD_QUERY_PRODUCT_INFO         0x1
#define CMD_QUERY_MCU_MODE             0x2
#define CMD_TELL_MCU_WIFI_STATUS       0x3
#define CMD_RESET_WIFI                 0x4
#define CMD_SELCT_AP_SMARTCONFIG       0x5*/


extern void uart_receive_input(unsigned char value);

void tuya_uart_send_byte(uint8_t val)
{
   usart_data_transmit(USART1, val);
   while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
}

void USART1_IRQHandler(void)
{
   #if 0
    static uint16_t frame_index;
    static uint16_t dat_len;
    if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE))
    {
        /* receive data */
        uint8_t dat = usart_data_receive(USART1);
        if(frame_state==FRAME_RECV_START)
        {
           if(dat==0x55)
           {  
              frame_index = 0;
              uart_recv_buf[frame_index++]=0x55;
           }
           else if((frame_index==1)&&(dat==0xaa))
           {
              uart_recv_buf[frame_index++]=0xaa;
              frame_state=FRAME_RECV_ING;
              dat_len=0;
           }
        }
        else if(frame_state==FRAME_RECV_ING)
        {
           uart_recv_buf[frame_index++]=dat;
           if(frame_index==6)
           {
              dat_len = (uint16_t)uart_recv_buf[4]<<8|(uint16_t)uart_recv_buf[5];
           }
           else if(frame_index>6)
           {
              if((frame_index-6)==dat_len+1)
              {
                 
                 uint16_t sum=0;
                 for(uint16_t i=0; i<frame_index-1; i++)
                 {
                    sum+=uart_recv_buf[i];
                 }
                 if(sum%256==uart_recv_buf[frame_index-1])
                 {
                    frame_state=FRAME_RECV_END;
                 }
                 else
                 {
                    frame_state=FRAME_RECV_START;
                 }
              }
           }
        }
        
    }
    #else 
    if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE))
    {
       uint8_t dat = usart_data_receive(USART1);
       uart_receive_input(dat);
    }
    else if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE_ORERR))
    {
       usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE_ORERR);
    }
    #endif
    //usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE);
}



/*void tuya_uart_send(uint8_t cmd, uint16_t dat_len, uint8_t *dat_ptr)
{
   uint16_t frame_len=0;
   uart_send_buf[frame_len++]=0x55;
   uart_send_buf[frame_len++]=0xaa;
   uart_send_buf[frame_len++]=UART_SEND_VER;
   uart_send_buf[frame_len++]=cmd; 
   uart_send_buf[frame_len++]=dat_len>>8&0xff;
   uart_send_buf[frame_len++]=dat_len&0xff;
   memcpy(&uart_send_buf[frame_len], dat_ptr, dat_len);
   frame_len+=dat_len;
   uint16_t sum=0;
   for(uint16_t i=0; i<frame_len; i++)
   {
      sum+=uart_send_buf[i];
   }
   uart_send_buf[frame_len]=sum;
   for(uint16_t i=0; i<frame_len+1; i++)
   {
      usart_data_transmit(USART1, uart_send_buf[i]);
      while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
   }
}

void tuya_uart_mainloop(void)
{
   uint8_t dat=0;
   if(frame_state==FRAME_RECV_END)
   {
      uint8_t cmd = uart_recv_buf[3];
      switch(cmd)
      {
         case CMD_HEART_BEAT:
              
              tuya_uart_send(CMD_HEART_BEAT, 1, &dat);
         break;
         case CMD_QUERY_PRODUCT_INFO:
              printf("hello\r\n");
         break;
      }
      frame_state = FRAME_RECV_START;
   }
}

*/

void tuya_uart_init(void)
{
   /* enable USART clock */
   rcu_periph_clock_enable(RCU_USART1);

   /* connect port to USART1_Tx */
   gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);  
   /* connect port to USART1_Rx */
   gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3);  

   /* configure USART Tx as alternate function push-pull */
   gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
   gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2);

   /* configure USART Rx as alternate function push-pull */
   gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3);
   gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3);

   /* USART configure */
   usart_deinit(USART1);
   usart_baudrate_set(USART1, 115200U);
   usart_receive_config(USART1, USART_RECEIVE_ENABLE);
   usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

   /* USART interrupt configuration */
   nvic_irq_enable(USART1_IRQn, 0);

   /* enable USART TBE interrupt */  
   usart_interrupt_enable(USART1, USART_INT_RBNE);
    
   usart_enable(USART1);
}


